/// [Double-base palindromes](https://projecteuler.net/problem=36)

fn main() {
    let list = generate_palindromes(6)
        .iter()
        .filter(|&&x| is_two_palindromes(x))
        .map(|x| *x)
        .collect::<Vec<usize>>();
    println!("{:?}", list);
    println!("sum: {}", list.iter().sum::<usize>());
}

fn generate_palindromes(max_digit: u32) -> Vec<usize> {
    let mut list = (1_usize..10).collect::<Vec<_>>();
    for digit in 2..=max_digit {
        for start in 1..=9 {
            let num = start + start * 10_usize.pow(digit - 1);
            let exp = digit / 2 - 1;
            let len = 10_usize.pow(exp);
            for a in 0..len {
                let mut t = a;
                let mut b = 0;
                for _ in 0..exp {
                    b = b * 10 + t % 10;
                    t /= 10;
                }
                if digit % 2 == 0 {
                    list.push(num + (a + b * len) * 10);
                } else {
                    let num = num + (a + b * len * 10) * 10;
                    for center in 0..=9 {
                        list.push(num + center * len * 10);
                    }
                }
            }
        }
    }
    list
}

fn is_two_palindromes(n: usize) -> bool {
    let list = format!("{:b}", n).chars().collect::<Vec<_>>();
    for i in 0..(list.len() / 2) {
        if list[i] != list[list.len() - i - 1] {
            return false;
        }
    }
    true
}

#[cfg(test)]
mod test {
    use super::*;
    #[test]
    fn good_generate_palindromes() {
        assert_eq!(generate_palindromes(1), vec![1, 2, 3, 4, 5, 6, 7, 8, 9]);
    }
    #[test]
    fn good_two_palindromes() {
        assert!(is_two_palindromes(585));
    }
}
